package com.zmn.plat.persistence.interfaces.product;

import com.zmn.common.dto.StatusDTO;
import com.zmn.plat.model.dto.product.ProductRelationDTO;
import com.zmn.plat.model.entity.category.ServCategAndCategTwoQuery;
import com.zmn.plat.model.entity.product.ProductQuery;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.model.entity.product.ServProductQuery;
import com.zmn.plat.model.entity.product.tariff.item.ProductTariffGroupItemQuery;
import com.zmn.plat.model.vo.channel.ChannelServProductVO;
import com.zmn.plat.model.vo.product.ProductAllMsgVO;
import com.zmn.plat.model.vo.product.ServProductBackVO;
import com.zmn.plat.model.vo.product.ServProductStatusVO;
import com.zmn.plat.model.vo.product.emissions.ProductEmissionsVO;
import com.zmn.plat.model.vo.product.tariff.item.ProductTariffGroupItemVo;
import org.apache.ibatis.annotations.Param;

import java.util.Date;
import java.util.List;

/**
 * ServProductDAO继承基类
 *
 * @author tanghongjun
 * @since 18/10/15 11:09
 */
public interface ServProductDAO {
    /**
     * 描述: ServProduct key 查询数据
     *
     * @param productId
     * @return: ServProduct
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    ServProduct findByKey(Integer productId);

    /**
     * 根据前台产品ID查询排放量
     *
     * @param showProductId
     * @return
     */
    Integer findTotalEmissionsByShowProductId(Integer showProductId);

    /**
     * 根据产品ID，查询产品所有信息
     *
     * @param productId
     * @return ProductAllMsgVO
     */
    ProductAllMsgVO findAllMsgByKey(Integer productId);

    /**
     * 描述:查询最大key
     *
     * @return: productId
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer findKeyForMax();

    /**
     * 描述:查询最大key
     *
     * @return: productId
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer findMaxShowSort();

    /**
     * 描述: 根据产品ID集合，查询产品所有信息
     *
     * @param productIdList 产品ID集合
     * @return List《ProductAllMsgVO》
     * @auther tanghongjun
     * @since 2020/3/24 11:21
     */
    List<ProductAllMsgVO> listAllMsgByKeys(@Param("productIdList") List<Integer> productIdList);

    /**
     * 描述: 根据查询条件，查询产品所有信息
     *
     * @param productQuery
     * @return List《ProductAllMsgVO》
     * @auther tanghongjun
     * @since 2020/3/24 11:21
     */
    List<ProductAllMsgVO> listAllMsgByProductQuery(ProductQuery productQuery);

    /**
     * 描述: 根据名称查询
     *
     * @param name
     * @return: List<ServProduct>
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    List<ServProduct> listByName(@Param("name") String name, @Param("showType") Integer showType);

    /**
     * 描述: 根据产品名称查询产品
     *
     * @param nameList 产品名称集合
     * @param showType 产品展示类型：1.后台，2.前台，3.计价器
     * @return List<ServProduct>
     * @auther tanghongjun
     * @since 2020年7月9日16:47:30
     */
    List<ServProduct> listByNameList(@Param("nameList") List<String> nameList, @Param("showType") Integer showType);

    /**
     * 查询所有满足计价器关系的前台产品
     *
     * @return
     */
    List<ServProduct> listShowProductSatisfyFaultRule(@Param("channelId") Integer channelId);

    /**
     * 描述: 根据服务分类和产品二级分类过滤产品 需要过滤掉渠道下架的产品
     *
     * @param channelId   渠道ID
     * @param servCategId 服务分类ID
     * @param categId     产品二级分类ID
     * @return 产品集合
     * @auther tanghongjun
     * @since 2019/9/2 14:41
     */
    List<ServProduct> listByChannelIdAndServCategIdAndCategId(@Param("channelId") Integer channelId, @Param("servCategId") Integer servCategId, @Param("categId") Integer categId);

    /**
     * 描述: 根据外部是否可用以及产品状态过滤产品二级分类
     *
     * @param status     产品状态
     * @param outsideUse 外部是否可用
     * @return 可用二级分类
     * @auther tanghongjun
     * @since 2019/6/10 14:54
     */
    List<Integer> findCategIds(@Param("servCategId") Integer servCategId, @Param("status") Integer status, @Param("outsideUse") Integer outsideUse);

    /**
     * 描述: 根据查询条件分页查询
     *
     * @param query
     * @return: List<ServProduct>
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    List<ServProduct> listPageByQuery(ServProductQuery query);

    /**
     * 描述: 前台产品根据查询条件分页查询
     *
     * @param query
     * @return: List<ServProduct>
     * @auther: tanbiao
     * @since: 2019/10/15 16:41
     */
    List<ServProduct> listPageByQueryForShow(ServProductQuery query);

    /**
     * 描述: 前台产品根据查询条件分页查询
     *
     * @param query
     * @return: List<ServProduct>
     * @auther: tanbiao
     * @since: 2019/10/15 16:41
     */
    List<ServProduct> listPageByQueryForTariff(ServProductQuery query);

    /**
     * 描述: 按照服务分类、一级分类、二级分类、产品的排序号升序排 查询产品（导出的时候用）
     *
     * @param query
     * @return List<ServProduct>
     * @auther tanghongjun
     * @since 2018/10/15 16:41
     */
    List<ServProduct> listPageByQueryForShowByCategSort(ServProductQuery query);

    /**
     * 描述: 查询后台产品是否关联
     *
     * @param productIds 产品id
     * @return: List<ServProduct>
     * @auther: tanbiao
     * @since: 2019/10/15 16:41
     */
    List<ServProduct> listProductHasRelated(@Param("productIds") List<Integer> productIds);

    /**
     * 描述: 查询前台产品是否关联 此处仅查询关联关系，针对一个前台产品多个后台产品，但是部分后台产品启用的情况下未作考虑
     *
     * @param productIds 产品id
     * @return: List<ServProduct>
     * @auther: tanbiao
     * @since: 2019/10/15 16:41
     */
    List<ServProductBackVO> listProductHasRelatedForShow(@Param("productIds") List<Integer> productIds);

    /**
     * 描述: 查询计价器产品是否关联 此处仅查询关联关系，针对一个计价器产品多个后台产品，但是部分后台产品启用的情况下未作考虑
     *
     * @param productIds 产品id
     * @return: List<ServProductBackVO>
     * @auther: tanbiao
     * @since: 2019/10/15 16:41
     */
    List<ServProductBackVO> listProductHasRelatedForTariff(@Param("productIds") List<Integer> productIds);

    /**
     * 描述：根据productIds查询产品所有状态（服务分类/一级分类/二级分类）
     *
     * @param productIds
     * @return
     */
    List<ServProductStatusVO> listProductStatusByProductIds(@Param("productIds") List<Integer> productIds);

    /**
     * 描述: 后台产品下架的检查，前台产品
     *
     * @param productIds 产品id
     * @return List<ServProduct>
     * @auther tanbiao
     * @since 2019/10/15 16:41
     */
    List<ServProductBackVO> listByProductIds(@Param("productIds") List<Integer> productIds);

    /**
     * 描述: 后台产品下架的检查，计价器产品
     *
     * @param productIds 产品id
     * @return List<ServProduct>
     * @auther tanbiao
     * @since 2019/10/15 16:41
     */
    List<ServProductBackVO> listTariffRelationBackProductsByProductIds(@Param("productIds") List<Integer> productIds);

    /**
     * 描述: 前台产品根据查询条件分页查询
     *
     * @param query
     * @return: List<ServProduct>
     * @auther: tanbiao
     * @since: 2019/10/15 16:41
     */
    List<ServProductBackVO> listPageByQueryForBackProduct(ServProductQuery query);

    /**
     * 描述: 后端根据查询条件分页查询（导出用）
     *
     * @param query
     * @return List<ServProduct>
     * @auther tanbiao
     * @since 2018/10/15 16:41
     */
    List<ServProductBackVO> listPageByQueryForBackProductByCategSort(ServProductQuery query);

    /**
     * 描述: 后端根据查询条件分页查询（导出用）
     *
     * @param query
     * @return List<ServProduct>
     * @auther tanbiao
     * @since 2018/10/15 16:41
     */
    List<ServProduct> listPageByQueryForTariffByCategSort(ServProductQuery query);

    /**
     * 描述: 根据查询条件查询所有数据
     *
     * @param query
     * @return: List<ServProduct>
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    List<ServProduct> listByQuery(ServProductQuery query);

    /**
     * 根据服务产品列表条件查询所有产品
     *
     * @Param: servProductList
     * @return: List<ServProduct>
     * @Author: zhuwenbing
     * @since: 2019/8/9 17:28
     */
    List<ServProduct> findAllProductByServProductList(@Param("servProductList") List<ServProductQuery> servProductList);

    /**
     * 描述: 根据前台产品ID查询支持计价器的后台产品 后台产品启用并且开通了计价器状态并且后台产品对应的计价器产品上架
     *
     * @param showProductId 前台产品ID
     * @return List《ServProduct》
     * @auther tanghongjun
     * @since 2020/3/27 18:08
     */
    List<ServProduct> listSupportByShowProductId(@Param("showProductId") Integer showProductId);

    /**
     * 描述: 根据计价器产品ID查询支持计价器的后台产品 后台产品启用并且开通了计价器状态并且后台产品对应的计价器产品上架
     *
     * @param traiffProductId 计价器产品ID
     * @return List《ServProduct》
     * @auther tanghongjun
     * @since 2020/3/27 18:08
     */
    List<ServProduct> listSupportByTariffProductId(@Param("traiffProductId") Integer traiffProductId);

    /**
     * 描述: 根据前台产品ID查询支持计价器对应的上架后台产品
     *
     * @param showProductId 前台产品ID
     * @return List《ServProduct》
     * @auther tanghongjun
     * @since 2020/3/27 18:08
     */
    List<ServProduct> listNormalBackProductByShowProductId(@Param("showProductId") Integer showProductId);

    /**
     * 描述: 根据计价器产品ID查询支持计价器对应的上架后台产品
     *
     * @param traiffProductId 计价器产品ID
     * @return List《ServProduct》
     * @auther tanghongjun
     * @since 2020/3/27 18:08
     */
    List<ServProduct> listNormalBackProductByTariffProductId(@Param("traiffProductId") Integer traiffProductId);

    /**
     * 描述: 查询配置了产品价格表并且有销售价的产品(添加筛选条件 例如小程序上选择的故障项目等)
     *
     * @param productFaultItemQuery
     * @return List<ServProduct>
     * @auther tanbiao
     * @since 2019/12/10 11:39
     */
    List<ProductTariffGroupItemVo> listProductHasTariffByQuery(ProductTariffGroupItemQuery productFaultItemQuery);

    /**
     * 根据后台产品ID集合查询满足计价器的后台产品
     *
     * @param productIdList 后台产品ID
     * @return ServProduct
     * @author tanbiao
     * @since 2020/3/28 14:15
     */
    List<ServProduct> listProductSupportTariff(@Param("list") List<Integer> productIdList);

    /**
     * 根据后台产品ID集合查询满足服务项的后台产品
     *
     * @param productIdList 后台产品ID
     * @return ServProduct
     * @author tanbiao
     * @since 2020/3/28 14:15
     */
    List<ServProduct> listProductSupportServ(@Param("list") List<Integer> productIdList);

    /**
     * 根据前台产品ID集合查询满足计价器的前台产品
     *
     * @param productIdList 前台产品ID
     * @return ServProduct
     * @author tanbiao
     * @since 2020/3/28 14:15
     */
    List<ServProduct> listShowProductSupportTariff(@Param("list") List<Integer> productIdList);

    /**
     * 根据前台产品ID集合查询满足服务项的前台产品
     *
     * @param productIdList 前台产品ID
     * @return ServProduct
     * @author tanbiao
     * @since 2020/3/28 14:15
     */
    List<ServProduct> listShowProductSupportServ(@Param("list") List<Integer> productIdList);

    /**
     * 描述: 根据产品ID集合查询产品集合
     *
     * @param productIdList
     * @return List<ServProduct>
     * @auther tanghongjun
     * @since 2018/10/15 16:41
     */
    List<ServProduct> listByIdList(@Param("productIdList") List<Integer> productIdList);

    /**
     * 描述: 根据产品ID集合查询产品集合
     *
     * @param productIdList
     * @return List<ServProduct>
     * @auther tanghongjun
     * @since 2018/10/15 16:41
     */
    List<ServProduct> listByIdListAndStatus(@Param("productIdList") List<Integer> productIdList, @Param("status") Integer status);

    /**
     * 描述: ServProduct 数据
     *
     * @return: List<ServProduct>
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    List<ServProduct> listAll();

    List<Integer> listAllIds();

    /**
     * 描述: 根据查询条件统计满足条件的数据条数
     *
     * @param query
     * @return: Integer
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer countByQuery(ServProductQuery query);

    /**
     * 描述: 前台产品根据查询条件统计满足条件的数据条数
     *
     * @param query
     * @return: Integer
     * @auther: tanbiao
     * @since: 2018/10/15 16:41
     */
    int countByQueryForShow(ServProductQuery query);

    /**
     * 描述: 前台产品根据查询条件统计满足条件的数据条数
     *
     * @param query
     * @return: Integer
     * @auther: tanbiao
     * @since: 2018/10/15 16:41
     */
    int countByQueryForTariff(ServProductQuery query);

    /**
     * 描述: 前台产品根据查询条件统计满足条件的数据条数
     *
     * @param query
     * @return: Integer
     * @auther: tanbiao
     * @since: 2018/10/15 16:41
     */
    int countByQueryForBackProduct(ServProductQuery query);

    /**
     * 描述: 根据主键修改数据
     *
     * @param servProduct
     * @return: 执行结果码
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer updateByKey(ServProduct servProduct);

    /**
     * 描述: 根据主键修改产品的状态
     *
     * @param servProduct
     * @return: 执行结果码
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer updateStatus(ServProduct servProduct);

    /**
     * 描述: 根据主键修改产品的排序
     *
     * @param servProduct
     * @return 执行结果码
     * @auther tanghongjun
     * @since 2018/10/15 16:41
     */
    void updateSortByKey(ServProduct servProduct);

    /**
     * 描述: 根据主键修改产品的排序
     *
     * @param servProduct
     * @return 执行结果码
     * @auther tanbiao
     * @since 2018/10/15 16:41
     */
    void updateShowSortByKey(ServProduct servProduct);

    /**
     * 描述: 批量修改排放量
     *
     * @param ids 产品id串集合
     * @return 执行结果码
     * @auther tanghongjun
     * @since 2020年8月27日15:56:36
     */
    void updateTotalEmissionsByKeys(@Param("ids") List<Integer> ids, @Param("totalEmissions") Integer totalEmissions, @Param("updater") String updater, @Param("updateTime") Date updateTime);

    /**
     * 描述: 批量修改状态
     *
     * @param dto
     * @return: 执行结果码
     * @auther: tanghongjun
     * @since: 2018/10/22 13:58
     */
    Integer updateStatusBatch(StatusDTO dto);

    /**
     * 描述: 批量修改计价器状态
     *
     * @param servProduct
     * @return: 执行结果码
     * @auther: tanbiao
     * @since: 2018/10/22 13:58
     */
    Integer updateTariffStatusBatch(ServProduct servProduct);

    /**
     * 描述: 批量修改产品描述
     *
     * @param productDesc
     * @return: 执行结果码
     * @auther: tanbiao
     * @since: 2018/10/22 13:58
     */
    Integer updateProductDescByCategIds(@Param("productDesc") String productDesc, @Param("categIds") List<ServCategAndCategTwoQuery> categIds, @Param("opeator") String opeator);

    /**
     * 描述: 新增数据
     *
     * @param servProduct
     * @return: 执行结果码
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer insert(ServProduct servProduct);

    /**
     * 描述: 根据主键删除数据
     *
     * @param productId
     * @return: 执行结果码
     * @auther: tanghongjun
     * @since: 2018/10/15 16:41
     */
    Integer deleteByKey(Integer productId);

    /**
     * 根据前台产品ID获取关联的后台产品集合
     *
     * @param productId 前台产品ID
     * @return List<ServProduct>
     * @author liuhaichuan
     * @since 2020/3/28 14:46
     */
    List<ServProduct> listBackProductByShowProductId(@Param("productId") Integer productId);

    /**
     * 根据后台产品ID查询没有关联产品组的产品ID（用途：后台产品上架时添加校验：所属服务分类+二级产品分类是否关联产品组）
     *
     * @param productIds
     * @return
     */
    List<Integer> listUnRelatedProductGroupByProductIdList(@Param("productIds") List<Integer> productIds);

    /**
     * 根据后台产品ID集合获取关联的前台产品集合
     *
     * @param productIds 后台产品ID集合
     * @return List<ServProduct>
     * @author liuhaichuan
     * @since 2020/3/28 14:46
     */
    List<ServProduct> listShowProductByBackProductId(@Param("productIds") List<Integer> productIds);

    /**
     * 根据计价器产品ID获取关联的后台产品集合
     *
     * @param productId 计价器产品ID
     * @return List<ServProduct>
     * @author liuhaichuan
     * @since 2020/3/28 14:46
     */
    List<ServProduct> listBackProductByTariffProductId(@Param("productId") Integer productId);

    /**
     * 根据后台产品ID集合获取关联的计价器产品集合
     *
     * @param productIds 后台产品ID集合
     * @return List<ServProduct>
     * @author liuhaichuan
     * @since 2020/3/28 14:46
     */
    List<ServProduct> listTariffProductByBackProductId(@Param("productIds") List<Integer> productIds);

    /**
     * 描述: 根据产品类型、服务分类ID，产品二级分类ID，产品状态，查询可用产品（工单可用） 可用：如果是查询前台产品，则其关联后台产品必须有一个是上架状态 如果是查询后台产品，则其对应的前台产品必须是上架状态 如果是查询计价器产品，则其关联的后台产品必须有一个是上架状态
     *
     * @param showType    产品展示类型：1.后台，2.前台，3.计价器
     * @param servCategId 服务分类ID
     * @param categTwoId  产品二级分类ID
     * @param status      产品状态
     * @return List《ProductAllMsgVO》
     * @since 2020年4月2日11:26:33
     */
    List<ProductAllMsgVO> listByShowTypeAndServCategAndCategAndStatus(@Param("showType") Integer showType, @Param("servCategId") Integer servCategId, @Param("categTwoId") Integer categTwoId,
                                                                      @Param("status") Integer status);

    /**
     * 根据产品ID集合和产品类型查询后台产品，计价器产品，前台产品的关联关系
     *
     * @param productIdList
     * @param showType      后台产品ID集合
     * @return List<ServProduct>
     * @author liuhaichuan
     * @since 2020/3/28 14:15
     */
    List<ProductRelationDTO> listProductRalationByIdListAndShowType(@Param("productIdList") List<Integer> productIdList, @Param("showType") Integer showType);

    /**
     * 描述: 根据渠道开通的前台分类集合查询产品
     *
     * @param servCategAndCategTwoQueries 分类集合
     * @auther tanbiao
     * @since 2021/03/25 14:35:30
     */
    List<ServProduct> listChannelSupportProductsByCategIds(@Param("queryList") List<ServCategAndCategTwoQuery> servCategAndCategTwoQueries, @Param("channelId") Integer channelId);


    /**
     * 描述: 查询前台产品总排放量
     *
     * @param showProductIds 前台产品ID
     * @return 产品排放量
     * @auther tanbiao
     * @since 2021/04/02 11:20
     */
    List<ProductEmissionsVO> listTotalEmissionsByShowProductIdList(@Param("showProductIds") List<Integer> showProductIds);

    /**
     * 描述: 条件查询产品集合
     * 条件： 渠道id或者名称模糊查询
     * 产品展示类型(前台/后台)
     * 服务分类id 一级产品id 二级产品id
     * 产品类型(渠道产品/通用产品)
     *
     * @param query query
     * @return java.util.List<com.zmn.plat.model.vo.channel.ChannelServProductVO>
     * @author jiafei
     * @since 2021/7/6 14:02
     */
    List<ChannelServProductVO> listChannelServProductByQuery(ServProductQuery query);

    /**
     * 优化
     *
     * @param query
     * @return
     */
    List<ProductAllMsgVO> listProductByQuery(ProductQuery query);

}